package org.dromara.hm.listener;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.excel.core.ExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.bo.HmCustomerBo;
import org.dromara.hm.domain.vo.HmCustomerExcelVo;
import org.dromara.hm.domain.vo.HmCustomerVo;
import org.dromara.hm.service.IHmCustomerService;
import org.dromara.hm.service.IHmProductService;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysUserService;

import java.util.List;

import static org.dromara.common.core.utils.DateUtils.convertToMonthDay;
import static org.dromara.common.core.utils.DateUtils.convertToStandardDate;

/**
 * 客户自定义导入
 *
 * @author Lion Li
 */
@Slf4j
public class HmCustomerImportListener extends AnalysisEventListener<HmCustomerExcelVo> implements ExcelListener<HmCustomerExcelVo>
{

    /**
     * 客户service
     */
    private final IHmCustomerService customerService;

    // 店铺dept Service
    private final ISysDeptService deptService;

    // 人员user Service
    private final ISysUserService userService;

    // 产品product Service
    private final IHmProductService productService;

    private final Boolean isUpdateSupport;

    private final Long operUserId;

    private int successNum = 0;

    private int failureNum = 0;

    private final StringBuilder successMsg = new StringBuilder();

    private final StringBuilder failureMsg = new StringBuilder();

    public HmCustomerImportListener(Boolean isUpdateSupport)
    {
        this.customerService = SpringUtils.getBean(IHmCustomerService.class);
        this.deptService = SpringUtils.getBean(ISysDeptService.class);
        this.userService = SpringUtils.getBean(ISysUserService.class);
        this.productService = SpringUtils.getBean(IHmProductService.class);
        this.isUpdateSupport = isUpdateSupport;
        this.operUserId = LoginHelper.getUserId();
    }

    @Override
    public void invoke(HmCustomerExcelVo customerVo, AnalysisContext context)
    {

        try
        {
            // 判断部门是否正常传递
            if (customerVo.getStoreName() == null || customerVo.getStoreName().isEmpty())
            {
                throw new ServiceException("店铺名称为空,请检查");
            }
            if (customerVo.getCustomerName() == null || customerVo.getCustomerName().isEmpty())
            {
                throw new ServiceException("客户名称为空,请检查");
            }
            if (customerVo.getStaffName() == null || customerVo.getStaffName().isEmpty())
            {
                throw new ServiceException("服务人员名称为空,请检查");
            }
            if (customerVo.getPhone() == null || customerVo.getPhone().isEmpty())
            {
                throw new ServiceException("客户电话名称为空,请检查");
            }
            // 判断customer
            HmCustomerVo hmCustomer = this.customerService.selectUserByCustomerName(customerVo.getPhone(), customerVo.getCustomerName());
            // 验证是否存在这个用户
            if (ObjectUtil.isNull(hmCustomer))
            {
                HmCustomerBo hmCustomerBo = BeanUtil.copyProperties(customerVo, HmCustomerBo.class);

                // 转换 customerBirth
                if (hmCustomerBo.getCustomerBirth() != null)
                {
                    String standardDate = convertToStandardDate(hmCustomerBo.getCustomerBirth());
                    hmCustomerBo.setCustomerBirth(standardDate); // 转换失败自动为null
                }

                // 转换 customerBirthDay
                if (StringUtils.isNotBlank(hmCustomerBo.getCustomerBirthday()))
                {
                    String monthDay = convertToMonthDay(hmCustomerBo.getCustomerBirthday());
                    hmCustomerBo.setCustomerBirthday(monthDay); // 转换失败自动为null
                }

                // 增加根据产品名称获取产品id,服务人员名称获取服务人员id,店铺名称获取店铺id
                translationIdToName(hmCustomerBo);
                ValidatorUtils.validate(hmCustomerBo);
                hmCustomerBo.setCreateBy(operUserId);
                if (hmCustomerBo.getStaffId() == null && hmCustomerBo.getIsPublic() == null)
                {
                    throw new RuntimeException("存在非本人维护客户或者公池标识为空,请检查");
                }
                customerService.insertByBo(hmCustomerBo);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、客户 ").append(hmCustomerBo.getCustomerName()).append(" 导入成功");
            }
            else if (isUpdateSupport)
            {
                Long customerId = hmCustomer.getCustomerId();
                HmCustomerBo customerBo = BeanUtil.toBean(customerVo, HmCustomerBo.class);
                customerBo.setCustomerId(customerId);
                ValidatorUtils.validate(customerBo);
                customerBo.setUpdateBy(operUserId);
                customerService.updateByBo(customerBo);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、客户 ").append(customerBo.getCustomerName()).append(" 更新成功");
            }
            else
            {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、客户 ").append(hmCustomer.getCustomerName()).append(" 已存在");
            }
        }
        catch (Exception e)
        {
            failureNum++;
            String msg = "<br/>" + failureNum + "、客户 " + customerVo.getCustomerName() + " 导入失败：";
            String message = e.getMessage();
            if (e instanceof ConstraintViolationException cvException)
            {
                message = StreamUtils.join(cvException.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
            }
            else if (e instanceof NumberFormatException nfe)
            {

                if (nfe.getMessage().split(":").length >= 2)
                {
                    message = "数据[" + nfe.getMessage().split(":")[1] + "]格式不正确，请输入数字,";
                }
                else
                {
                    message = "数据[" + nfe.getMessage() + "]格式不正确，请输入数字,";
                }

            }
            failureMsg.append(msg).append(message);
            log.error(msg, e);
        }
    }

    /**
     * 翻译数据
     */
    private void translationIdToName(HmCustomerBo hmCustomerBo) throws Exception
    {
        // 根据店铺名称获取店铺id
        if (StringUtils.isNotBlank(hmCustomerBo.getStoreName()))
        {
            SysDeptBo deptBo = new SysDeptBo();
            deptBo.setDeptName(hmCustomerBo.getStoreName());
            deptBo.setDeptCategory("DP");
            deptBo.setAncestors("101");
            List<SysDeptVo> sysDeptVos = deptService.selectDeptList(deptBo);
            if (sysDeptVos.isEmpty())
            {
                throw new ServiceException("店铺不存在");
            }
            hmCustomerBo.setStoreId(sysDeptVos.get(0).getDeptId());
            hmCustomerBo.setStoreName(sysDeptVos.get(0).getDeptName());
        }
        // 根据服务人员名称获取服务人员id
        if (StringUtils.isNotBlank(hmCustomerBo.getStaffName()))
        {
            SysUserVo sysUserVo = userService.selectUserByUserName(hmCustomerBo.getStaffName());
            if (ObjectUtil.isEmpty(sysUserVo))
            {
                throw new ServiceException("服务人员不存在");
            }
            // 若当前登录人为admin则允许全部新增,若不为admin则只允许新增自己的用户
            if (LoginHelper.isSuperAdmin(LoginHelper.getUserId()))
            {
                hmCustomerBo.setStaffId(sysUserVo.getUserId());
                hmCustomerBo.setStaffName(sysUserVo.getNickName());
            }
            else if (sysUserVo.getUserId().equals(LoginHelper.getUserId()))
            {
                hmCustomerBo.setStaffId(LoginHelper.getUserId());
                hmCustomerBo.setStaffName(sysUserVo.getNickName());
            }

        }
        else if (hmCustomerBo.getIsPublic() != null)
        {
            // 公池用户
            hmCustomerBo.setIsPublic(Boolean.TRUE);
        }

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context)
    {

    }

    @Override
    public ExcelResult<HmCustomerExcelVo> getExcelResult()
    {
        return new ExcelResult<>()
        {

            @Override
            public String getAnalysis()
            {
                if (failureNum > 0)
                {
                    failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
                    throw new ServiceException(failureMsg.toString());
                }
                else
                {
                    successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
                }
                return successMsg.toString();
            }

            @Override
            public List<HmCustomerExcelVo> getList()
            {
                return null;
            }

            @Override
            public List<String> getErrorList()
            {
                return null;
            }
        };
    }
}
